<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:csharp="http://csharp.org" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">

<msxsl:script language="CSharp" implements-prefix="csharp">
<![CDATA[

	
	public double circumference(double radius)
	{
		return 2 * Math.PI * radius;
	}
	
	public string lines(string input)
	{
		String points = input.Replace(" ","|");
		return "http://maps.google.com/maps/api/staticmap?path=fillcolor:0xAA000033|color:0x0000ff|weight:5|"+points+"&size=512x512&sensor=false";
	}
	
	public string simplePointOnMap(string lat, string lon)
	{
		return "http://maps.google.com/maps/api/staticmap?zoom=12&size=512x512&markers=color:blue|"+lat+","+lon+"&sensor=false";
	}
	
	public string iconPointOnMap(string lat, string lon, string fullIcon)
	{
		string root = "http://urlimg.com/resize/16x16/";
		string icon = root+"http://maps.google.com/mapfiles/kml/shapes/triangle.png";
		string iconic = "https://urlimg.s3.amazonaws.com/553898e9de2bee987f9c70eb7668a04dc34925b98016cd16b87363da?Signature=Mc382px5wdmvryxepV%2FgdQv7pr4%3D&Expires=1292026790&AWSAccessKeyId=1N07QRVTGQR0R74JF2R2";
			string tiny = "http://bit.ly/i6LkHD";
		return "http://maps.google.com/maps/api/staticmap?zoom=12&size=512x512&markers=color:blue|shadow:false|icon:"+fullIcon+"|"+lat+","+lon+"&sensor=false";
	}

	
	public string circle(string input)
	{
		string[] parts=input.Split(' ');
		string[] strCoords = parts[0].Split(',');
		string strRadius = parts[1];
		
		double lat = Double.Parse(strCoords[0]);
		double lon =Double.Parse(strCoords[1]);
		double radius = Double.Parse(strRadius);
		
		// fallback to just marking a point on the map
		if(radius < 0.1){
				return "http://maps.google.com/maps/api/staticmap?size=512x512&markers=color:blue|label:S|"+lat+","+lon+"&sensor=false";
		}
		
		String points = "";
		for(int deg=0; deg<360; deg+=15){
			points+=calculateDerivedLat(lat, lon, radius*1000.0, deg);
			points+=",";
			points+=calculateDerivedLon(lat, lon, radius*1000.0, deg);
			points += "|";
		}
		
		//repeat first point to close the loop
		points+=calculateDerivedLat(lat, lon, radius*1000.0, 0.0);
		points+=",";
		points+=calculateDerivedLon(lat, lon, radius*1000.0, 0.0);
		
		return "http://maps.google.com/maps/api/staticmap?path=fillcolor:0xAA000033|color:0x0000ff|weight:5|"+points+"&size=512x512&sensor=false";

	}
	
	public const double EarthRadius = 6378137.0;
	
	// from: http://stackoverflow.com/questions/1125144/how-do-i-find-the-lat-long-that-is-x-km-north-of-a-given-lat-long
	/// <summary>
	/// Calculates the end-point from a given source at a given range (meters) and bearing (degrees).
	/// This methods uses simple geometry equations to calculate the end-point.
	/// </summary>
	/// <param name="source">Point of origin</param>
	/// <param name="range">Range in meters</param>
	/// <param name="bearing">Bearing in degrees</param>
	/// <returns>End-point from the source given the desired range and bearing.</returns>
	public static double calculateDerivedLat(double srcLat, double srcLon, double range, double bearing)
	{
		double latA = srcLat * (Math.PI/180.0);
		double lonA = srcLon * (Math.PI/180.0);
		double angularDistance = range / EarthRadius;
		double trueCourse = bearing * (Math.PI/180.0);
	
		double lat = Math.Asin(
			Math.Sin(latA) * Math.Cos(angularDistance) + 
			Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));
	
		return lat * (180.0/Math.PI);
	}




	// from: http://stackoverflow.com/questions/1125144/how-do-i-find-the-lat-long-that-is-x-km-north-of-a-given-lat-long
	/// <summary>
	/// Calculates the end-point from a given source at a given range (meters) and bearing (degrees).
	/// This methods uses simple geometry equations to calculate the end-point.
	/// </summary>
	/// <param name="source">Point of origin</param>
	/// <param name="range">Range in meters</param>
	/// <param name="bearing">Bearing in degrees</param>
	/// <returns>End-point from the source given the desired range and bearing.</returns>
	public static double calculateDerivedLon(double srcLat, double srcLon, double range, double bearing)
	{
		double latA = srcLat * (Math.PI/180.0);
		double lonA = srcLon * (Math.PI/180.0);
		double angularDistance = range / EarthRadius;
		double trueCourse = bearing * (Math.PI/180.0);
	
		double lat = Math.Asin(
			Math.Sin(latA) * Math.Cos(angularDistance) + 
			Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));
	
		double dlon = Math.Atan2(
			Math.Sin(trueCourse) * Math.Sin(angularDistance) * Math.Cos(latA), 
			Math.Cos(angularDistance) - Math.Sin(latA) * Math.Sin(lat));
	
		double lon = ((lonA + dlon + Math.PI) % (Math.PI * 2.0)) - Math.PI;
	
		return lon * (180.0/Math.PI);
	}

]]>
</msxsl:script>
		
	

</xsl:stylesheet>
